﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using System.IO;
using System.ComponentModel.Composition;

namespace ETRoboCon.TrackingSystem.SwitchBoxEmulater
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    [Export(typeof(ETRoboConTrakingSystem.ISwitchBoxDevice))]
    [ExportMetadata("DeviceType","Emulator")]
    public partial class MainWindow : Window, ETRoboConTrakingSystem.ISwitchBoxDevice
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private DateTime startTimestamp;
        private readonly Int64 timeUnit = 1000000;

        #region ISwitchBoxDevice Members

        public void Start(ETRoboConTrakingSystem.ISwitchBoxClient client)
        {
            startTimestamp = DateTime.Now;

            sbReferee.OnLeftSideButtonPushed += new SwitchBoxView.ButtonPushHandler(sbReferee_OnStartButtonPushed);
            sbReferee.OnRightSideButtonPushed += new SwitchBoxView.ButtonPushHandler(sbReferee_OnResetButtonPushed);
            sbInCourse.OnLeftSideButtonPushed += new SwitchBoxView.ButtonPushHandler(sbInCourse_OnGoalButtonPushed);
            sbInCourse.OnRightSideButtonPushed += new SwitchBoxView.ButtonPushHandler(sbInCourse_OnRetireButtonPushed);
            sbOutCourse.OnLeftSideButtonPushed += new SwitchBoxView.ButtonPushHandler(sbOutCourse_OnGoalButtonPushed);
            sbOutCourse.OnRightSideButtonPushed += new SwitchBoxView.ButtonPushHandler(sbOutCourse_OnRetireButtonPushed);

            client.OnSwitchBoxLEDStatusChanged += new ETRoboConTrakingSystem.SwitchBoxLEDStatus(client_OnSwitchBoxLEDStatusChanged);
            client.SetDevice(this);
        }

        void client_OnSwitchBoxLEDStatusChanged(bool start, bool reset, bool goalIn, bool retireIn, bool goalOut, bool retireOut)
        {
            string kind = "(start,reset,goal-in,retire-in,goal-out,retire-out)";
            sbReferee.LeftSideButtonLED=start;
            sbReferee.RightSideButtonLED=reset;
            sbInCourse.LeftSideButtonLED=goalIn;
            sbInCourse.RightSideButtonLED=retireIn;
            sbOutCourse.LeftSideButtonLED=goalOut;
            sbOutCourse.RightSideButtonLED=retireOut;

            StringBuilder sb = new StringBuilder(tbStatus.Text);
            TextWriter writer = new StringWriter(sb);
            writer.WriteLine(string.Format("{0}:{1}", (DateTime.Now - startTimestamp).Ticks, kind));
            writer.WriteLine(string.Format("        {0},{1},{2},{3},{4},{5}", start, reset, goalIn, retireIn, goalOut, retireOut));
            tbStatus.Text = sb.ToString();
        }

        void sbOutCourse_OnRetireButtonPushed(string kindName, string buttonSide, DateTime timestamp)
        {
            Int64 tick = (timestamp - startTimestamp).Ticks;
            if (OnButtonStatusChanged != null)
            {
                OnButtonStatusChanged(ETRoboConTrakingSystem.SwitchBoxButtonType.RETIRE_OUT, tick / timeUnit);
            }

            UpdateStatus(tick, "Out Course", "Retire");
        }

        private void UpdateStatus(Int64 tick, string panel, string kind)
        {
            StringBuilder sb = new StringBuilder(tbStatus.Text);
            TextWriter writer = new StringWriter(sb);
            writer.WriteLine(String.Format("{0}:{1} {2} Pushed", tick, panel, kind));
            tbStatus.Text = sb.ToString();
        }

        void sbOutCourse_OnGoalButtonPushed(string kindName, string buttonSide, DateTime timestamp)
        {
            Int64 tick = (timestamp - startTimestamp).Ticks;
            if (OnButtonStatusChanged != null)
            {
                OnButtonStatusChanged(ETRoboConTrakingSystem.SwitchBoxButtonType.GOAL_OUT, tick / timeUnit);
            }

            UpdateStatus(tick, "Out Course", "Goal");
        }

        void sbInCourse_OnRetireButtonPushed(string kindName, string buttonSide, DateTime timestamp)
        {
            Int64 tick = (timestamp - startTimestamp).Ticks;
            if (OnButtonStatusChanged != null)
            {
                OnButtonStatusChanged(ETRoboConTrakingSystem.SwitchBoxButtonType.RETIRE_IN, tick / timeUnit);
            }

            UpdateStatus(tick, "In Course", "Retier");
        }

        void sbInCourse_OnGoalButtonPushed(string kindName, string buttonSide, DateTime timestamp)
        {
            Int64 tick = (timestamp - startTimestamp).Ticks;
            if (OnButtonStatusChanged != null)
            {
                OnButtonStatusChanged(ETRoboConTrakingSystem.SwitchBoxButtonType.GOAL_IN, tick / timeUnit);
            }

            UpdateStatus(tick, "In Course", "Goal");
        }

        void sbReferee_OnResetButtonPushed(string kindName, string buttonSide, DateTime timestamp)
        {
            Int64 tick = (timestamp - startTimestamp).Ticks;
            if (OnButtonStatusChanged != null)
            {
                OnButtonStatusChanged(ETRoboConTrakingSystem.SwitchBoxButtonType.RESET, tick / timeUnit);
            }

            UpdateStatus(tick, "Referee", "Reset");
        }

        void sbReferee_OnStartButtonPushed(string kindName, string buttonSide, DateTime timestamp)
        {
            Int64 tick = (timestamp - startTimestamp).Ticks;
            if (OnButtonStatusChanged != null)
            {
                OnButtonStatusChanged(ETRoboConTrakingSystem.SwitchBoxButtonType.START, tick / timeUnit);
            }

            UpdateStatus(tick, "Referee", "Start");
        }

        public void Stop()
        {
//            throw new NotImplementedException();
        }

        public event ETRoboConTrakingSystem.SwitchBoxButtonStatusChanged OnButtonStatusChanged;

        #endregion
    }
}
